' Klassenraumloesung: GUI
' Copyright (c) 2009 Michael Schaefer, Immo-Gert Birn
' 
' Permission is hereby granted, free of charge, to any person obtaining a copy
' of this software and associated documentation files (the "Software"), to deal
' in the Software without restriction, including without limitation the rights
' to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
' copies of the Software, and to permit persons to whom the Software is
' furnished to do so, subject to the following conditions:
' 
' The above copyright notice and this permission notice shall be included in
' all copies or substantial portions of the Software.
' 
' THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
' IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
' FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
' AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
' LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
' OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
' THE SOFTWARE.

Import MaxGUI.Drivers
Import MaxGUI.ProxyGadgets

SuperStrict

'Include "crypt.bmx"

Incbin "toolbar.bmp"
Incbin "ampel_grau.bmp"
Incbin "ampel_gruen.bmp"
Incbin "ampel_gelb.bmp"
Incbin "ampel_rot.bmp"

Const VERSION:String = "Klassenraum Version 0.1"

Const INI:String = "raeume.ini"

Const c_lehrer:Int = 1
Const c_schueler:Int = 2

Const c_status_unknown:Int = 0
Const c_status_nicht_gesperrt:Int = 1
Const c_status_gesperrt:Int = 2

Const BTN_HEIGHT:Int = 24 ' Pixel
Const SPACE:Int      = 30 ' Platz zwichen 2 Btns, in Pixel

'##############################################################################
Type TPc
  Field name:String
  Field status:Int = c_status_unknown
  Field row:Int
  Field column:Int

  Method Create:TPc(name:String, row:Int, column:Int)
    Self.name = name
    Self.row = row
    Self.column = column
    DebugLog name
    Return Self
  EndMethod
EndType


'##############################################################################
Type TRaum
  Field name:String
  Field pcs:TList   = CreateList()
  Field rows:Int    = 0
  Field columns:Int = 0
  
  Method Create:TRaum(name:String)
    Self.name = name
    DebugLog name
    Return Self
  EndMethod ' TRaum.Create
  
  Method addPc(pc:TPc)
    If Not pc Then Return
    pcs.addlast(pc)
    If pc.row + 1 > Self.rows Then Self.rows = pc.row + 1
    If pc.column + 1 > Self.columns Then Self.columns = pc.column + 1
  EndMethod ' TRaum.addPc
EndType ' TRaum

'##############################################################################
' Checkbox mit Text und Icon darunter
Type TIconCheckBox
  Field btn:TGadget
  Field panel:TGadget
  Field width:Int
  Field height:Int

  Method Create:TIconCheckBox(window:TGadget, x:Int, y:Int, b:Int, txt:String, icon:TPixmap)
    Self.btn = CreateButton(txt,x,y,b,BTN_HEIGHT,window,BUTTON_CHECKBOX)
    SetGadgetLayout Self.btn,EDGE_RELATIVE,EDGE_RELATIVE,EDGE_RELATIVE,EDGE_RELATIVE
    SetGadgetToolTip(Self.btn, txt)
    Self.panel = CreatePanel(x,y+BTN_HEIGHT,icon.width,icon.height,window)
    SetGadgetLayout Self.panel,EDGE_RELATIVE,EDGE_RELATIVE,EDGE_RELATIVE,EDGE_RELATIVE
    SetGadgetToolTip(Self.panel, txt)
    Self.width = GadgetWidth(btn)
    If Self.width < GadgetWidth(Self.panel) Then Self.width = GadgetWidth(Self.panel)
    Self.height = GadgetHeight(Self.panel) + GadgetHeight(Self.btn)

    SetGadgetPixmap(panel,icon)
    Return Self
  EndMethod ' TIconCheckBox.Create
EndType

'##############################################################################
' die GUI-Klasse
Type TGui
  Field mainWin:Tgadget
  Field toolbar:TGadget
  Field scrollArea:TScrollPanel
  Field pcs:TList = CreateList()
  Field raeume:TRaum[]

  Method Create:TGui(raeume:TRaum[])
    Self.raeume = raeume
    _createWindow()
    Return Self
  EndMethod ' TGui.Create

  Method onEvent(event:TEvent)
    Select event.id
      Case EVENT_WINDOWCLOSE
        End
      Case EVENT_TIMERTICK
      Case EVENT_GADGETACTION
        Select event.source
          Case toolbar
            Select event.data
              Case 0 ' select all
                _toogleAllBtns(True)
              Case 1 ' unselect all
                _toogleAllBtns(False)
            EndSelect ' toolbar
        EndSelect 'select event.source for EVENT_GADGETACTION
    EndSelect ' select event.id
  EndMethod ' onEvent

  Method _createWindow()
    Local lr:Int = 30 ' linker Rand
    Local xstart:Int = 20
    Local x:Int  = xstart
    Local ystart:Int = 20
    Local y:Int  = ystart
    Local w:Int  = 72 ' Breite der Ampel-Bilder in Pixel
    Local h:Int  = 70

    
    mainWin = CreateWindow(VERSION,0,0,GadgetWidth(Desktop()), GadgetHeight(Desktop()) - 30, Null, ..
              WINDOW_RESIZABLE | WINDOW_STATUS | WINDOW_TITLEBAR ..
              | WINDOW_CLIENTCOORDS | WINDOW_MENU )

    toolbar = CreateToolbar( "incbin::toolbar.bmp", 0, 0, 0, 0, mainWin )
    SetToolbarTips(toolbar,["Alles auswaehlen", "Nichts auswaehlen", "",..
                            "Ausgewaehlte PCs sperren", "Ausgewaehlte PCs entsperren", ..
                            "Ausgewaehlte PCs herunterfahren", "Auffrischen"])
    scrollArea = CreateScrollPanel( 0, 0, ClientWidth(mainWin), ClientHeight(mainWin), mainWin, SCROLLPANEL_SUNKEN )
    SetGadgetLayout( scrollArea, EDGE_RELATIVE, EDGE_RELATIVE, EDGE_RELATIVE, EDGE_RELATIVE )
    Local pcPanel:TGadget = ScrollPanelClient(scrollArea)

    Local icon:TPixmap = LoadPixmap("ampel_rot.bmp")

    Local raum:TRaum = raeume[0]
    For Local pc:TPc = EachIn raum.pcs
      y = pc.row * ( SPACE + w ) + xstart
      x = pc.column * ( space + h ) + ystart
      Local ttt:TIconCheckBox = New TIconCheckBox.Create(pcPanel, x, y, w, pc.name, icon)
      pcs.addlast(ttt)
    Next
	  FitScrollPanelClient( scrollArea, SCROLLPANEL_SIZETOKIDS )
  EndMethod ' TGui.CreateWindow()

  Method _toogleAllBtns(checked:Int)
    For Local pc:TIconCheckBox = EachIn pcs
      SetButtonState(pc.btn, checked)
    Next
  EndMethod
EndType


'##############################################################################
' INI-Datei auswerten
Function leseRaeume:TRaum[]()
  Local inifile:TStream=ReadFile(INI)
  If Not inifile RuntimeError "Konnte Initialisierungsdatei " + INI + " nicht oeffnen!"

  Local r:TList = CreateList()
  Local raum:TRaum
  Local row:Int
  Local column:Int
  While Not Eof(inifile)
    Local line:String = ReadLine(inifile).Trim()
    If Not line Then Continue               ' Leerzeilen ignorieren
    If line.startswith("#") Then Continue   ' Kommentarzeilen ignorieren
    If line.startswith("[") And line.endswith("]") Then
      Local name:String=line[1..line.length-1]
      raum = New TRaum.Create(name)
      r.addlast(raum)
      row    = 0
      column = 0  
      Continue
    EndIf
    If (Not raum) Then RuntimeError "Illegales Format in Datei " + INI + " !"
    Local pcs:String[] = line.split(",")
    column = 0
    For Local i:Int = 0 To pcs.length -1
      Local name:String = pcs[i].Trim()
      If name <> "0" Then
        Local pc:TPc = New TPc.Create(pcs[i].Trim(), row, column)
        raum.addPc(pc)
      EndIf
      column :+ 1
    Next
    row :+ 1
  Wend
  CloseStream(inifile)

  Return TRaum[](r.toArray())
EndFunction

'##############################################################################
'################### Hauptprogramm ############################################
'##############################################################################

Local raeume:TRaum[] = leseRaeume()
Local gui:TGui = New TGui.Create(raeume)
' 1 Hz Timer
CreateTimer(1)

Repeat
  WaitEvent()
  gui.onEvent(CurrentEvent)
Forever
